/**
* dbsvr 主逻辑
*/

#ifndef __DBSVR_CTRL_H__
#define __DBSVR_CTRL_H__

#include "dbdef.h"
#include "CTSizeString.h"
#include "CDataUpdateMgr.h"

#include "commerrno.h"

#define CDBEpollObject CTEpollObject<CDBCtrl>

namespace __gnu_cxx
{
    template<> struct hash<CVarObjectKey>
    {
        size_t operator()(const CVarObjectKey& s) const
        {
            return ((__stl_hash_string(s.m_sStrID.Get())*214013)+
                ((CT_UINT64_LOW(s.m_u64ID)+CT_UINT64_HIGH(s.m_u64ID))* 214013 + 2531011)
                +s.m_chDataType)& 0x7FFFFFFF;
        }
    };

    typedef CTSizeString<USER_TOKEN_LEN> SZ_USER_TOKEN;
    template<> struct hash<SZ_USER_TOKEN>
    { 
        size_t operator()(const SZ_USER_TOKEN& s) const
        {
            return __stl_hash_string(s.Get());
        }
    };
}

class CDBCtrl
{
public:
    CDBCtrl();
	~CDBCtrl();

    static CDBCtrl * m_pstMain;

    int Init();
    int Run();
    int Exit();

    static void sigusr1_handle(int iSigVal);
    static void sigusr2_handle(int iSigVal);

    void OnEnpShmQueueEvent(CDBEpollObject* pstObject, SOCKET iSocket, int iEvent);
    void OnMpShmQueueEvent(CDBEpollObject* pstObject, SOCKET iSocket, int iEvent);

    void DoNotResetShm()
    {
        m_bResetShm = false;
    }

    /**
    * 向mpsvr发送请求
    */
    int RequestToMp(const char* pszBuf, int iBufLen);

    /**
    * 向客户端返回简单的错误响应: CTMsgHead + CResult
    */
    int AnswerToClient(CEnpNetHead& stHead, CTCodeStream& s);
	int AnswerToClient(CEnpNetHead& stHead, CTMsgHead& stMsgHead, CResult& stRet);
    int AnswerToClient(CEnpNetHead& stHead, const char* sAnsMsg, int MsgLen);

protected:
    void DumpStatInfo();

    /**
    * 处理来自客户端的消息
    */
    void HandleEnpMsg();

    /**
    * 处理来自dbsvr的消息
    */
    void HandleMpMsg();

    int InitBuilding();
    int InitBuildingRank();

public:
    unsigned int		m_uiNow;    ///< 当前时间

    CTBuffer			    m_stEncodeBuf;  ///< 编码缓冲区
    CTBuffer			    m_stDecodeBuf;  ///< 解码缓冲区

    CTSizeString<MAX_DBNAME_LEN>   m_szDBName;   //数据库名称

    static int UpdateData(CVarObject * pstObj, CVarObjectKey * pstKey);

    /*************************************************
    Description:    获取数据，从UpdateMgr中获取数据
    Input:          @stKey 更新数据的ｋｅｙ
    @szData 用于存放数据的内存空间指针
    @iMaxSize 数据空间最大长度
    return          0 表示找到数据且有效，3 数据已经在删除中
    *************************************************/
    template<typename KEY>
    static int GetDataFromUpdateMgr(KEY & stKey,char * szData, int iMaxSize, CVarObjectHead& stHead)
    {
        int iRet = CDBCtrl::m_pstMain->m_stUpdateMgr.GetData(stKey, szData, iMaxSize, stHead);
        if (iRet == 0) //找到数据
        {
            if(stHead.m_iDataInfo == VOP_DELETE)
            {
                CT_TRACE(("data was deleted"));
                return RET_DATA_DELETED;
            }

        }

        return iRet;
    }


    template<typename T>
    static const char* DataEncode(T& stData, int& iLen)
    {
        iLen = 0;
        static char szDataBuf[CTMsgHead::EMAX_MSGLEN];
        CTBuffer stBuff;
        stBuff.Attach(szDataBuf,CTMsgHead::EMAX_MSGLEN,0);

        CTCodeStream s(stBuff);
        CodeConvert(s, stData, NULL, bin_encode());
        if (s.m_iRet != 0)
        {
            return NULL;
        }

        iLen = s.m_ushPos;
        return s.m_pszBuf;
    }

    template<typename T>
    static int DataDecode(T& stData, char* sBuf, int iLen)
    {
        if (sBuf == NULL || iLen > CTMsgHead::EMAX_MSGLEN || iLen <= 0)
        {
            return -1;
        }

        CTCodeStream s(sBuf, iLen);

        CodeConvert(s, stData, NULL, bin_decode());
        if (s.m_iRet != 0)
        {
            return -2;
        }

        return 0;
    }


    template<typename T>
    int FromMysqlEncodeToBinEncode(CTCodeStream& from, CTCodeStream& to, T& t)
    {
        CodeConvert(from, t, NULL, mysql_decode());
        if (from.m_iRet)
        {
            CT_WARNING(("decode error: %d", from.m_iRet));
            return from.m_iRet;
        }

        CodeConvert(to, t, NULL, bin_encode());
        if (to.m_iRet)
        {
            CT_WARNING(("encode error: %d", to.m_iRet));
            return to.m_iRet;
        }

        return 0;
    }

protected:
    static bool s_bReloadConfig;
    static bool s_bExit;
    bool                    m_bResetShm; //是否重载内存中的数据

    CTEpoll				    m_stEpoll;
    CTShmQueue<CDBCtrl>     m_stEnpShmQueue;
    CTShmQueue<CDBCtrl>     m_stMpShmQueue;
    CTShm                   m_stMgrShm;
    CTShm                   m_stUpdateMgrShm;

    CTStat				    m_stStat;

public:
    CUpdateDataMgr<CVarObjectKey>          m_stUpdateMgr; 

    CTHashObjectMgr<CTSizeString<USER_TOKEN_LEN>, CGidList>   m_stUserTokenToGID;   //用户标识映射表
};



#endif //__DBSVR_CTRL_H__
